load("@rules_erlang//:erlang_app.bzl", "erlang_app", "test_erlang_app")
load("@rules_erlang//:xref2.bzl", "xref")
load("@rules_erlang//:dialyze.bzl", "dialyze", "plt")
load("@rules_erlang//:ct.bzl", "assert_suites2", "ct_suite")
load(":util.bzl", "common_root_as_var")

APP_NAME = "lz4"

APP_DESCRIPTION = "An LZ4 compression library that wraps an NIF"

APP_VERSION = module_version()

DEPS = [
    "@host_triple//:erlang_app",
]

# NOTE: lz4 headers are referenced with <> paths in c_src, so they
#       need to be supplied in the deps to :lz4_nif_linux. This
#       means cc_import must be used, and because cc_import does not
#       appear to relative-ize any paths, we use genrule to place
#       the files appropriately
genrule(
    name = "liblz4_files",
    srcs = [
        "@lz4_src//:lib/lz4.h",
        "@lz4_src//:lib/lz4frame.h",
    ] + select({
        "//toolchains:cross_compile_arm64": ["@lz4_src//:static_library_arm64"],
        "//conditions:default": ["@lz4_src//:static_library"],
    }),
    outs = [
        "lz4.h",
        "lz4frame.h",
        "liblz4.a",
    ],
    cmd = "cp $(SRCS) $(RULEDIR)",
)

cc_import(
    name = "liblz4",
    hdrs = [
        ":lz4.h",
        ":lz4frame.h",
    ],
    static_library = ":liblz4.a",
)

common_root_as_var(
    name = "erlang_headers_dir",
    srcs = [
        "@rules_erlang//tools:erlang_headers",
    ],
)

common_root_as_var(
    name = "nif_helpers_dir",
    srcs = [
        "@nif_helpers//:nif_helpers.h",
    ],
)

common_root_as_var(
    name = "lz4_headers_dir",
    srcs = [
        ":liblz4_files",
    ],
)

cc_binary(
    name = "lz4_nif",
    srcs = glob([
        "c_src/**/*.c",
        "c_src/**/*.h",
    ]) + [
        "@nif_helpers//:nif_helpers.c",
        "@nif_helpers//:nif_helpers.h",
        "@rules_erlang//tools:erlang_headers",
    ],
    copts = [
        "-I $(ERLANG_HEADERS_DIR)",
        "-I $(NIF_HELPERS_DIR)",
        "-I $(LZ4_HEADERS_DIR)",
        "-fPIC",
    ] + select({
        "@platforms//os:macos": ["-Wno-implicit-function-declaration"],
        "//conditions:default": [],
    }),
    linkopts = select({
        "@platforms//os:macos": ["-Wl,-undefined,dynamic_lookup"],
        "//conditions:default": [],
    }),
    linkshared = True,
    toolchains = [
        ":erlang_headers_dir",
        ":nif_helpers_dir",
        ":lz4_headers_dir",
    ],
    deps = [
        ":liblz4",
    ],
)

genrule(
    name = "lz4_nif_so",
    srcs = [":lz4_nif"],
    outs = ["priv/lz4_nif.so"],
    cmd = "cp $< $@",
)

erlang_app(
    app_description = APP_DESCRIPTION,
    app_name = APP_NAME,
    app_version = APP_VERSION,
    extra_priv = ["priv/lz4_nif.so"],
    deps = DEPS,
)

test_erlang_app(
    app_description = APP_DESCRIPTION,
    app_name = APP_NAME,
    app_version = APP_VERSION,
    extra_priv = ["priv/lz4_nif.so"],
    deps = DEPS,
)

xref()

plt(
    name = "deps_plt",
    apps = [
        "erts",
        "kernel",
        "stdlib",
        "compiler",
        "crypto",
    ],
    for_target = ":erlang_app",
)

dialyze(
    size = "small",
    plt = ":deps_plt",
)

genrule(
    name = "place_reference_file",
    srcs = ["@pdf_reference//file"],
    outs = ["test/lz4f_SUITE_data/pdf_reference_1-7.pdf"],
    cmd = "cp $< $@",
)

ct_suite(
    name = "lz4f_SUITE",
    data = [
        "test/lz4f_SUITE_data/pdf_reference_1-7.pdf",
    ],
    runtime_deps = [
        "@ct_helper//:erlang_app",
    ],
)

assert_suites2()
